home *** CD-ROM | disk | FTP | other *** search
/ GFX Sensations 1 / Graphic Sensations - Volume 1.iso / tools / amiga / 3d_tools / irit40s.lha / Irit / cagd_lib / cagdbbox.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-30  |  5.6 KB  |  177 lines

  1. /******************************************************************************
  2. * CagdBbox.c - Handle freeform cuves and surfaces bounding boxes.          *
  3. *******************************************************************************
  4. * Written by Gershon Elber, Jan. 92.                          *
  5. ******************************************************************************/
  6.  
  7. #include "cagd_loc.h"
  8.  
  9. #define RESET_BBOX(BBox) { \
  10.     BBox -> Min[0] = BBox -> Min[1] = BBox -> Min[2] = INFINITY; \
  11.     BBox -> Max[0] = BBox -> Max[1] = BBox -> Max[2] = -INFINITY; }
  12.  
  13. static void CagdPointsBBox(CagdRType **Points, int Length, CagdBBoxStruct *BBox);
  14.  
  15. /******************************************************************************
  16. * Computes a bounding box around a freeform curve.                  *
  17. ******************************************************************************/
  18. void CagdCrvBBox(CagdCrvStruct *Crv, CagdBBoxStruct *BBox)
  19. {
  20.     CagdCrvStruct
  21.     *E3Crv = CagdCoerceCrvTo(Crv, CAGD_PT_E3_TYPE);
  22.     int Length = E3Crv -> Length;
  23.     CagdRType
  24.     **Points = E3Crv -> Points;
  25.  
  26.     CagdPointsBBox(Points, Length, BBox);
  27.  
  28.     CagdCrvFree(E3Crv);
  29. }
  30.  
  31. /******************************************************************************
  32. * Computes a bounding box around a list of freeform curves.              *
  33. ******************************************************************************/
  34. void CagdCrvListBBox(CagdCrvStruct *Crvs, CagdBBoxStruct *BBox)
  35. {
  36.     RESET_BBOX(BBox);
  37.  
  38.     for ( ; Crvs != NULL; Crvs = Crvs -> Pnext) {
  39.     CagdBBoxStruct TmpBBox;
  40.  
  41.     CagdCrvBBox(Crvs, &TmpBBox);
  42.     CagdMergeBBox(BBox, &TmpBBox);
  43.     }
  44. }
  45.  
  46. /******************************************************************************
  47. * Computes a bounding box around a freeform surface.                  *
  48. ******************************************************************************/
  49. void CagdSrfBBox(CagdSrfStruct *Srf, CagdBBoxStruct *BBox)
  50. {
  51.     CagdSrfStruct
  52.     *E3Srf = CagdCoerceSrfTo(Srf, CAGD_PT_E3_TYPE);
  53.     int Length = E3Srf -> ULength * E3Srf -> VLength;
  54.     CagdRType
  55.     **Points = E3Srf -> Points;
  56.  
  57.     CagdPointsBBox(Points, Length, BBox);
  58.  
  59.     CagdSrfFree(E3Srf);
  60. }
  61.  
  62. /******************************************************************************
  63. * Computes a bounding box around a list of freeform surfaces.              *
  64. ******************************************************************************/
  65. void CagdSrfListBBox(CagdSrfStruct *Srfs, CagdBBoxStruct *BBox)
  66. {
  67.     RESET_BBOX(BBox);
  68.  
  69.     for ( ; Srfs != NULL; Srfs = Srfs -> Pnext) {
  70.     CagdBBoxStruct TmpBBox;
  71.  
  72.     CagdSrfBBox(Srfs, &TmpBBox);
  73.     CagdMergeBBox(BBox, &TmpBBox);
  74.     }
  75. }
  76.  
  77. /******************************************************************************
  78. * Computes a bounding box of a set of points.                      *
  79. ******************************************************************************/
  80. static void CagdPointsBBox(CagdRType **Points, int Length, CagdBBoxStruct *BBox)
  81. {
  82.     int i;
  83.  
  84.     RESET_BBOX(BBox);
  85.  
  86.     for (i = 0; i < Length; i++) {
  87.     if (BBox -> Min[0] > Points[X][i])
  88.         BBox -> Min[0] = Points[X][i];
  89.     if (BBox -> Min[1] > Points[Y][i])
  90.         BBox -> Min[1] = Points[Y][i];
  91.     if (BBox -> Min[2] > Points[Z][i])
  92.         BBox -> Min[2] = Points[Z][i];
  93.  
  94.     if (BBox -> Max[0] < Points[X][i])
  95.         BBox -> Max[0] = Points[X][i];
  96.     if (BBox -> Max[1] < Points[Y][i])
  97.         BBox -> Max[1] = Points[Y][i];
  98.     if (BBox -> Max[2] < Points[Z][i])
  99.         BBox -> Max[2] = Points[Z][i];
  100.     }
  101. }
  102.  
  103. /******************************************************************************
  104. * Merge (union) two bounding boxes into one.                      *
  105. ******************************************************************************/
  106. void CagdMergeBBox(CagdBBoxStruct *DestBBox, CagdBBoxStruct *SrcBBox)
  107. {
  108.     int i;
  109.  
  110.     for (i = 0; i < 3; i++) {
  111.     if (DestBBox -> Min[i] > SrcBBox -> Min[i])
  112.         DestBBox -> Min[i] = SrcBBox -> Min[i];
  113.     if (DestBBox -> Max[i] < SrcBBox -> Max[i])
  114.         DestBBox -> Max[i] = SrcBBox -> Max[i];
  115.     }
  116. }
  117.  
  118. /******************************************************************************
  119. * Computes a min max bound on a curve in a given axis.                  *
  120. * The curve is not coerced to anything and the given axis is tested directly  *
  121. * where 0 is the W axis and 1, 2, 3 are the X, Y, Z etc.              *
  122. ******************************************************************************/
  123. void CagdCrvMinMax(CagdCrvStruct *Crv, int Axis,
  124.            CagdRType *Min, CagdRType *Max)
  125. {
  126.     CagdBType
  127.     IsNotRational = !CAGD_IS_RATIONAL_CRV(Crv);
  128.     int i,
  129.     Length = Crv -> Length,
  130.     MaxCoord = CAGD_NUM_OF_PT_COORD(Crv -> PType);
  131.     CagdRType
  132.     *Pts = Crv -> Points[Axis],
  133.     *WPts = IsNotRational ? NULL : Crv -> Points[0];
  134.  
  135.     if ((Axis == 0 && IsNotRational) ||    (Axis > MaxCoord))
  136.     FATAL_ERROR(CAGD_ERR_WRONG_CRV);
  137.  
  138.     for (i = 0, *Min = INFINITY, *Max = -INFINITY; i < Length; i++) {
  139.     CagdRType
  140.         V = WPts ? Pts[i] / WPts[i] : Pts[i];
  141.  
  142.     if (*Max < V)
  143.         *Max = V;
  144.     if (*Min > V)
  145.         *Min = V;
  146.     }
  147. }
  148.  
  149. /******************************************************************************
  150. * Computes a min max bound on a curve in a given axis (1 for X, 2 for Y etc.).*
  151. ******************************************************************************/
  152. void CagdSrfMinMax(CagdSrfStruct *Srf, int Axis,
  153.            CagdRType *Min, CagdRType *Max)
  154. {
  155.     CagdBType
  156.     IsNotRational = !CAGD_IS_RATIONAL_SRF(Srf);
  157.     int i,
  158.     Length = Srf -> ULength * Srf -> VLength,
  159.     MaxCoord = CAGD_NUM_OF_PT_COORD(Srf -> PType);
  160.     CagdRType
  161.     *Pts = Srf -> Points[Axis],
  162.     *WPts = IsNotRational ? NULL : Srf -> Points[0];
  163.  
  164.     if ((Axis == 0 && IsNotRational) ||    (Axis > MaxCoord))
  165.     FATAL_ERROR(CAGD_ERR_WRONG_SRF);
  166.  
  167.     for (i = 0, *Min = INFINITY, *Max = -INFINITY; i < Length; i++) {
  168.     CagdRType
  169.         V = WPts ? Pts[i] / WPts[i] : Pts[i];
  170.  
  171.     if (*Max < V)
  172.         *Max = V;
  173.     if (*Min > V)
  174.         *Min = V;
  175.     }
  176. }
  177.